package com.zyd.shiro.business.service;

import java.util.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;

import com.zyd.shiro.business.vo.OrderDetailVO;
import com.zyd.shiro.business.vo.OrderGoodsVO;
import com.zyd.shiro.business.vo.OrderVO;
import com.zyd.shiro.persistence.beans.*;
import com.zyd.shiro.persistence.dao.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * 服务层
 *
 * @author RookieWZW
 */
@Service
public class MallOrderService {

    @Autowired
    private MallOrderDao orderDao;

    @Autowired
    private MallOrderGoodsDao orderGoodsDao;

    @Autowired
    private MallUserDao userDao;

    @Autowired
    private MallGoodsImageDao goodsImageDao;

    @Autowired
    private MallOrderAddressDao orderAddressDao;

    /**
     * 查询所有订单
     *
     * @return
     */
    public List<Order> findAll() {

        return orderDao.findAll();
        /*List<Order> orderList = orderDao.findAll();
        return OrderToOrderVo(orderList);*/

    }

    /**
     * 查询未发货的订单
     *
     * @return
     */
    public List<Order> findAllByDelivery(Integer status) {

        return orderDao.getAllByDelivery_status(status, 20);
    }

    /**
     * 查询待收货的订单
     *
     * @return
     */
    public List<Order> findAllByReceipt(Integer status) {
        return orderDao.getAllByReceipt_statusAAndDelivery_status(status, 20);
    }

    /**
     * 查询待付款的订单
     *
     * @return
     */
    public List<Order> findAllByPay(Integer status) {
        return orderDao.getAllByPay_status(status);
    }


    public List<Order> getAllByPay_statusAndDelivery_statusAndReceipt_status(Integer Paystatus, Integer deliveryStatus, Integer receiptStatus) {

        return orderDao.getAllByPay_statusAndDelivery_statusAndReceipt_status(Paystatus, deliveryStatus, receiptStatus);

    }

    /**
     * 查询或取消的订单
     *
     * @return
     */
    public List<Order> findAllByStatus(Integer status) {

        return orderDao.getAllByOrder_status(status);
    }


    public Page<Order> findPage(int page, int size) {
        PageRequest pageRequest = new PageRequest(page - 1, size);
        return orderDao.findAll(pageRequest);
    }

    private Specification<Order> where(Map searchMap) {

        return new Specification<Order>() {

            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();
                // 雪花算法实现？
                if (searchMap.get("order_no") != null && !"".equals(searchMap.get("order_no"))) {
                    predicateList.add(cb.like(root.get("order_no").as(String.class), "%" + (String) searchMap.get("order_no") + "%"));
                }

                // 起始时间
                if (searchMap.get("start_date") != null && !"".equals(searchMap.get("start_date"))) {
                    predicateList.add(cb.greaterThanOrEqualTo(root.get("create_time").as(Date.class), (Date) searchMap.get("start_date")));
                }
                // 终止时间
                if (searchMap.get("end_date") != null && !"".equals(searchMap.get("end_date"))) {
                    predicateList.add(cb.lessThanOrEqualTo(root.get("create_time").as(Date.class), (Date) searchMap.get("end_date")));
                }
                if (searchMap.get("pay_status") != null && !"".equals(searchMap.get("pay_status"))) {
                    predicateList.add(cb.equal(root.get("pay_status").as(Integer.class), (Integer) searchMap.get("pay_status")));
                }
                if (searchMap.get("delivery_status") != null && !"".equals(searchMap.get("delivery_status"))) {
                    predicateList.add(cb.equal(root.get("delivery_status").as(Integer.class), (Integer) searchMap.get("delivery_status")));
                }
                if (searchMap.get("receipt_status") != null && !"".equals(searchMap.get("receipt_status"))) {
                    predicateList.add(cb.equal(root.get("receipt_status").as(Integer.class), (Integer) searchMap.get("receipt_status")));
                }
                if (searchMap.get("order_status") != null && !"".equals(searchMap.get("order_status"))) {
                    predicateList.add(cb.equal(root.get("order_status").as(Integer.class), (Integer) searchMap.get("order_status")));
                }


                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));

            }
        };

    }

    public Page<Order> findSearch(String whereString, int page, int size) {
        Map whereMap = new HashMap<>();
        Specification<Order> specification = null;
        switch (whereString) {
            case "delivery":
                whereMap.put("pay_status", 20);
                whereMap.put("delivery_status", 10);
                whereMap.put("receipt_status", 10);
                break;
            case "receipt":
                whereMap.put("pay_status", 20);
                whereMap.put("delivery_status", 20);
                whereMap.put("receipt_status", 10);
                break;
            case "pay":
                whereMap.put("pay_status", 10);
                whereMap.put("delivery_status", 10);
                whereMap.put("receipt_status", 10);
                break;
            case "finish":
                whereMap.put("pay_status", 20);
                whereMap.put("delivery_status", 20);
                whereMap.put("receipt_status", 20);
                break;
            case "cancel":
                whereMap.put("order_status", 10);
                break;
            default:
                break;
        }
        specification = where(whereMap);
        PageRequest pageRequest = new PageRequest(page - 1, size);
        return orderDao.findAll(specification, pageRequest);
    }

    public List<Order> findSearch(Map whereMap) {
        Specification<Order> specification = where(whereMap);

        return orderDao.findAll(specification);
    }

    public Order findOne(Integer id) {

        return orderDao.findOne(id);

    }

    public void updatePrice(Map updateMap, Integer id) {
        Order order = orderDao.findOne(id);
        order.setTotal_price(Double.valueOf((String) updateMap.get("total_price")));
        order.setExpress_price(Double.valueOf((String) updateMap.get("express_price")));
        orderDao.save(order);
    }

    public void delivery(Map infoMap, Integer id) {
        Order order = orderDao.findOne(id);
        order.setTotal_price(Double.valueOf((String) infoMap.get("express_company")));
        order.setExpress_price(Double.valueOf((String) infoMap.get("express_no")));
        order.setDelivery_status(20);
        order.setDelivery_time(new Date());
        orderDao.save(order);

    }

    private List<OrderVO> OrderToOrderVo(List<Order> orderList) {
        List<OrderVO> orderVOList = new ArrayList<>();

        for (Order order : orderList) {
            OrderVO orderVO = new OrderVO();
            orderVO.setCreate_time(order.getCreate_time());
            orderVO.setPay_price(order.getPay_price());
            orderVO.setOrder_no(order.getOrder_no());
            orderVO.setExpress_price(order.getExpress_price());
            orderVO.setDelivery_status(order.getDelivery_status());
            orderVO.setPay_status(order.getPay_status());
            orderVO.setReceipt_status(order.getReceipt_status());
            orderVO.setOrder_status(order.getOrder_status());
            User user = userDao.findOne(order.getUser_id());
            orderVO.setUser_id(order.getUser_id());


            List<OrderGoods> orderGoodsList = orderGoodsDao.findAllByOrder_id(order.getId());
            System.out.println(orderGoodsList);
            for (int i = 0; i < 20; i++) {
                System.out.println("&&&&&&&&&&");
            }
            List<OrderGoodsVO> orderGoodsVOList = new ArrayList<>();

            for (OrderGoods orderGoods : orderGoodsList) {
                OrderGoodsVO orderGoodsVO = new OrderGoodsVO();

                orderGoodsVO.setGoods_name(orderGoods.getGoods_name());
                orderGoodsVO.setGoods_price(orderGoods.getGoods_price());
                orderGoodsVO.setTotal_num(orderGoods.getTotal_num());
                GoodsImage goodsImage = goodsImageDao.findOne(orderGoods.getImage_id());

                orderGoodsVO.setImage(goodsImage.getImage());

                orderGoodsVOList.add(orderGoodsVO);
            }

            System.out.println(orderGoodsVOList);
            for (int i = 0; i < 20; i++) {
                System.out.println("&&&&&&&&&&");
            }
            orderVO.setOrderGoodsVOList(orderGoodsVOList);
            orderVOList.add(orderVO);
        }

        return orderVOList;
    }

    public void UpdateDelivery(String eco, String eno, Integer id) {
        Order order = orderDao.findOne(id);
        order.setExpress_company(eco);
        order.setExpress_no(eno);
        order.setDelivery_status(20);
        order.setDelivery_time(new Date());
        orderDao.save(order);
    }


}
